package com.tools.cleanmaster.ui.view;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.DrawFilter;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.graphics.PaintFlagsDrawFilter;
import android.graphics.Point;
import android.graphics.Rect;
import android.graphics.drawable.BitmapDrawable;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.View;
import android.view.animation.DecelerateInterpolator;
import android.view.animation.OvershootInterpolator;

import com.nineoldandroids.animation.Animator;
import com.nineoldandroids.animation.AnimatorListenerAdapter;
import com.nineoldandroids.animation.ValueAnimator;
import com.nineoldandroids.animation.ValueAnimator.AnimatorUpdateListener;
import com.tools.cleanmaster.R;
import com.tools.cleanmaster.utils.LogHelper;

public class CompleteMarkView extends View {

    public interface AnimationListener {
        void lightAnimationFinished();
    }

    private static final int MARK_MAX_RADIUS = 100;
    private static final int LIGHT_START_RADIUS = (int) (MARK_MAX_RADIUS * (175f / 209f));
    private static final int LIGHT_WIDTH = 0;

    private Context mContext;
    private Bitmap mCompleteMark;//对勾
    private Rect mMarkBound;
    private ValueAnimator mPopOutAnimator;
    private int mMarkRadius;
    private int mMarkMaxRadius;
    private int mLightRadius;
    private int mLightStartRadius;
    private int mMaxRadius;
    private Point mCenterPoint;
    private ValueAnimator mLightAnimator;
    private boolean mNeedRefresh;
    private Paint mLightPaint;
    private int mLightWidth;
    private int mLightAlpha;
    private AnimationListener mListener;
    private DrawFilter mDrawFilter;

    public CompleteMarkView(Context context) {
        super(context);
        init(context);
    }

    public CompleteMarkView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(context);
    }

    public CompleteMarkView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context);
    }

    static int dipToPx(Context context, int dip) {
        return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dip, context.getResources().getDisplayMetrics());
    }

    private void init(Context context) {
        mContext = context;
        mNeedRefresh = false;
        mMarkMaxRadius = dipToPx(mContext, MARK_MAX_RADIUS);
        mLightWidth = dipToPx(mContext, LIGHT_WIDTH);
        mLightStartRadius = dipToPx(mContext, LIGHT_START_RADIUS);

        mDrawFilter = new PaintFlagsDrawFilter(0, Paint.ANTI_ALIAS_FLAG);
        mLightPaint = new Paint();
        mLightPaint.setAntiAlias(true);
        mLightPaint.setColor(Color.WHITE);
        mLightPaint.setStyle(Style.STROKE);
        mLightPaint.setStrokeWidth(mLightWidth);
        mLightPaint.setAlpha(mLightAlpha);

        mPopOutAnimator = ValueAnimator.ofFloat(0, 1);
        mLightAnimator = ValueAnimator.ofFloat(0, 1);
        mPopOutAnimator.setDuration(1000);
        mLightAnimator.setDuration(2000);
        mPopOutAnimator.setInterpolator(new OvershootInterpolator());
        mLightAnimator.setInterpolator(new DecelerateInterpolator());
        mPopOutAnimator.addUpdateListener(new AnimatorUpdateListener() {

            @Override
            public void onAnimationUpdate(ValueAnimator animator) {
                float markAnimationProgress = (Float) animator.getAnimatedValue();
                mMarkRadius = (int) (markAnimationProgress * mMarkMaxRadius);
            }
        });
        mLightAnimator.addUpdateListener(new AnimatorUpdateListener() {

            @Override
            public void onAnimationUpdate(ValueAnimator animator) {
                float lightAnimationProgress = (Float) animator.getAnimatedValue();
                mLightRadius = (int) (mLightStartRadius + lightAnimationProgress
                        * (mMaxRadius - mLightStartRadius));
                mLightAlpha = (int) (0xaf * (1 - lightAnimationProgress));
            }
        });
        mPopOutAnimator.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                mLightAnimator.start();
            }
        });
        mLightAnimator.addListener(new AnimatorListenerAdapter() {

            @Override
            public void onAnimationEnd(Animator animation) {
                mNeedRefresh = false;
                if (mListener != null) {
                    mListener.lightAnimationFinished();
                }
            }
        });
        mCompleteMark = ((BitmapDrawable) context.getResources().getDrawable(
                R.drawable.complete_mark)).getBitmap();
        mMarkBound = new Rect();
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        initDrawParams(w, h);
    }

    private void initDrawParams(int w, int h) {
        if (w != h) {
            w = h;
        }
        mMaxRadius = w / 2;
        mCenterPoint = new Point(w / 2, h / 2);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        canvas.setDrawFilter(mDrawFilter);
        super.onDraw(canvas);
        drawCompleteMark(canvas);
        drawLightRing(canvas);
        refreshControl();
    }

    private void refreshControl() {
        if (mNeedRefresh) {
            this.postInvalidate();
        }
    }

    private void drawLightRing(Canvas canvas) {
        if (mLightRadius < mLightStartRadius) {
            return;
        }
        if (mCenterPoint == null) {
            return;
        }
        mLightPaint.setAlpha(mLightAlpha);
        canvas.drawCircle(mCenterPoint.x, mCenterPoint.y, mLightRadius, mLightPaint);
    }

    private void drawCompleteMark(Canvas canvas) {
        if (mMarkBound == null || mCompleteMark == null || mCenterPoint == null) {
            return;
        }
        mMarkBound.set(mCenterPoint.x - mMarkRadius, mCenterPoint.y - mMarkRadius, mCenterPoint.x + mMarkRadius,
                mCenterPoint.y + mMarkRadius);
        LogHelper.i("drawCompleteMark", mMarkBound.toString());
        canvas.drawBitmap(mCompleteMark, null, mMarkBound, null);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }

    public void setAnimationListener(AnimationListener listener) {
        mListener = listener;
    }

    public void startAnimation() {
        mNeedRefresh = true;
        mLightAlpha = 0;
        this.postInvalidate();
        mPopOutAnimator.start();
    }
}
